package com.hyacinth.lotterysystem.service.activityStatus.impl;

import com.hyacinth.lotterysystem.common.errocde.ServiceErrorCodeConstants;
import com.hyacinth.lotterysystem.common.exception.ServiceException;
import com.hyacinth.lotterysystem.service.ActivityService;
import com.hyacinth.lotterysystem.service.activityStatus.ActivityStatusManager;
import com.hyacinth.lotterysystem.service.activityStatus.ConvertActivityStatusDTO;
import com.hyacinth.lotterysystem.service.activityStatus.operater.AbstractActivityOperator;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Service
public class ActivityStatusManagerImpl implements ActivityStatusManager {
    private static final Logger logger = LoggerFactory.getLogger(ActivityStatusManagerImpl.class);
    @Resource
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();

    @Resource
    private ActivityService activityService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {

        if (CollectionUtils.isEmpty(operatorMap)) {
            logger.warn("operatorMap 为空");
            return;
        }

        Map<String, AbstractActivityOperator> currmap = new HashMap<>(operatorMap);
        Boolean update = false;
        // 处理人员 奖品  查询活动关联的奖品信息 判断奖品状态是否需要扭转 奖品: INIT -> COMPLETED
        update = processConvertStatus(convertActivityStatusDTO, currmap, 1);

        // 处理活动
        update = processConvertStatus(convertActivityStatusDTO, currmap, 2) || update;

        // 更新活动信息完整缓存
        if (update) {
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }
    }

    @Override
    public void rollbackHandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        // 活动 人员 奖品
        for (AbstractActivityOperator operator : operatorMap.values()) {
            operator.convert(convertActivityStatusDTO);
        }
    }

    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> currmap, int sequence) {
        Boolean update = false;
        // 遍历currmap
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator = currmap.entrySet().iterator();
        while (iterator.hasNext()) {
            AbstractActivityOperator operator = iterator.next().getValue();
            // 判断是否需要转换
            if (operator.sequence() != sequence || !operator.needConvert(convertActivityStatusDTO))
                continue;

            // operator是否需要转换
            if (!operator.convert(convertActivityStatusDTO)) {
                logger.error("{} 状态转换失败!", operator.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }
            iterator.remove();
            update = true;
        }
        return update;
    }
}
